#include "rwip.h" // RW SW initialization
#include "co_debug.h"
#include "app.h"
#include "peripheral.h"
#include "co_debug.h"

#include "device.h"
#include "component.h"
#include "debug_config.h"

#define GT31X_LOG(format, ...) __OSAL_LOG("[GT31X.c] " C_GREEN format C_NONE "\r\n", ##__VA_ARGS__)

#define GT31X_VIRTUALHARDWARE vIIC_9
/*********************************************************************
 * TYPEDEFS
 */

#define TOUCH_SLAVE_ADDR (0xB0 >> 1)

static uint8_t GT31X_reg_init = 0;

static uint8_t GT31X_I2C_Write(uint8_t *data, uint8_t len)
{
    return Device_Write(GT31X_VIRTUALHARDWARE, data, len, TOUCH_SLAVE_ADDR);
    // return i2c_master_write((uint16_t)TOUCH_SLAVE_ADDR, data, len);
}

static uint8_t GT31X_I2C_Read(uint8_t *data, uint8_t len)
{
    return Device_Read(GT31X_VIRTUALHARDWARE, data, len, TOUCH_SLAVE_ADDR);
    // return i2c_master_write((uint16_t)TOUCH_SLAVE_ADDR, data, len);
}

uint8_t TouchWriteByte(uint8_t bAddr, uint8_t bData)
{
    uint8_t tmp[2];
    tmp[0] = bAddr;
    tmp[1] = bData;
    GT31X_I2C_Write(tmp, 2);
}

uint8_t TouchReadByte(uint8_t bAddr, uint8_t *pbData)
{
    uint8_t ret, tmp[2];
    tmp[0] = bAddr;
    GT31X_I2C_Write(tmp, 1);
    ret = GT31X_I2C_Read(pbData, 1);
    return ret;
}
uint8_t TouchWrite(uint8_t bAddr, uint8_t *pbData, uint8_t bLen)
{
    uint8_t tmp[100];
    tmp[0] = bAddr;
    memcpy(&tmp[1], pbData, bLen);
    return GT31X_I2C_Write(tmp, bLen + 1);
}
uint8_t TouchRead(uint8_t bAddr, uint8_t *pbData, uint8_t bLen)
{
    uint8_t tmp[2];
    tmp[0] = bAddr;
    GT31X_I2C_Write(tmp, 1);
    return GT31X_I2C_Read(pbData, bLen);
}
/*********************************************************************
 * @fn 	 	 GT31X_init
 *
 * @brief	 TMS12 init
 *
 * @param	 none
 *
 * @return  return 1/0
 ************************************************************************/
#define IIC_SPEED_STANDARD_MODE 100000 /* 标准100K */
#define IIC_SPEED_FAST_MODE 400000     /* 快速100K */
#define IIC_SPEED_HIGH_MODE 3400000    /* 高速3.4M */

#define GT31X_RST_PIN vPIN_C38 //

#define TOUCH_CHANNGES 14

#define mTouchRegOutput1 0x02
#define mTouchRegOutput2 0x03
#define mTouchAddrKeyRead mTouchRegOutput1
#define mTouchCountReadKeyReg 2

static int abTouchSenOffsetInit[TOUCH_CHANNGES] =
    {
        // 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13,
        33,//8
        33,//0
        35,//*
        34,//5
        33,//7
        34,//4
        35,//2
        32,//1
        36,//3
        33,//6
        33,//#
        32,//9
        27,
        35,
};

void GT31X_Register_Init(void)
{
    uint8_t i;
    for (i = 0; i < 3; i++)
    {
        uint8_t bTemp;
        TouchReadByte(0x01, &bTemp);
        // TouchRead(0x01,bTemp,4);
        if (bTemp == 0xB0)
        {
            GT31X_reg_init = 1;
            break;
        }
        GT31X_LOG("GT31X_dev_Init err bTemp=%02X", bTemp);
        co_delay_ms(2);
    }

    if (GT31X_reg_init)
    {
        TouchWriteByte(0x0B, 0x01); /*软复位开始*/
        TouchWriteByte(0x0B, 0x00); /*软复位结束*/
        TouchWriteByte(0x10, 0x00); /*中断输出脉冲模式，单键模式*/
        TouchWriteByte(0x14, 0x00); /*按键扫描时间 11ms 左右*/
        TouchWriteByte(0x19, 0x01); /*开启滑动模式*/

        TouchWriteByte(0x66, 0x02);
        TouchWriteByte(0x40, 0x02);
        TouchWriteByte(0x41, 0x01);
        TouchWriteByte(0x42, 0x01);
        TouchWriteByte(0x43, 0x00);
        TouchWriteByte(0x44, 0x02);
        TouchWriteByte(0x45, 0x03);
        TouchWriteByte(0x46, 0x00);
        TouchWriteByte(0x47, 0x02);
        TouchWriteByte(0x13, 0x05); /*自动校准时间 500ms 左右*/

        TouchWriteByte(0x04, 0xFF); //每个通道(SIN1~8)使能/禁用位
        TouchWriteByte(0x05, 0x3F); //每个通道(SIN9~14)使能/禁用位

        //        TouchWriteByte(0x60, 0x01);
        //        TouchWriteByte(0x61, 0x1C);
        //        TouchWriteByte(0x62, 0x0F);
        //        TouchWriteByte(0x63, 0x0C);
        //        TouchWriteByte(0x64, 0x05);
        //        TouchWriteByte(0x65, 0x2A);
        //        TouchWriteByte(0x69, 0x13);
        //        TouchWriteByte(0x0A, 0x30);

        uint8_t abSensitivity[TOUCH_CHANNGES] = {0};
        int val = -8;
#if TEST_TOUCH_SENSITIVITY
        val = dataWhileSleep.Sensitivity;
        if (val < 15 || val > 60)
            val = 15;
        memset(abSensitivity, val, TOUCH_CHANNGES);
#else
        for (i = 0; i < TOUCH_CHANNGES; i++)
        {
            abSensitivity[i] = abTouchSenOffsetInit[i] + val;
        }

#endif
        TouchWrite(0x20, abSensitivity, sizeof(abSensitivity)); /* 设置按键灵敏度，根据需求调整 */
    }
}
static void GT31X_Rest(void)
{
    Device_Write(vPIN_C38, NULL, 0, 0);
    co_delay_ms(5);
    Device_Write(vPIN_C38, NULL, 0, 1);
    co_delay_ms(10);
}
static int GT31X_init(void)
{
    pinmux_config(IIC_SCL_PIN, PINMUX_I2C_MST_SCK_CFG);
    pinmux_config(IIC_SDA_PIN, PINMUX_I2C_MST_SDA_CFG);
    pmu_pin_mode_set((1 << IIC_SDA_PIN) | (1 << IIC_SCL_PIN), PMU_PIN_MODE_OD_PU);
    // i2c_open(I2C_MODE_MASTER, IIC_SPEED_STANDARD_MODE);
    co_delay_ms(1);
    return 0;
}

/**
 * @brief  GT31X驱动，Read接口
 * @note
 * @param  pCmd：命令
 *         param：参数---还需根据param来添加特征值处理
 *
 * @return SUCCESS   ERROR
 */
// #define KEY_0_GT314_MAP 5
// #define KEY_1_GT314_MAP 4
// #define KEY_2_GT314_MAP 8
// #define KEY_3_GT314_MAP 9
// #define KEY_4_GT314_MAP 3
// #define KEY_5_GT314_MAP 7
// #define KEY_6_GT314_MAP 10
// #define KEY_7_GT314_MAP 2
// #define KEY_8_GT314_MAP 6
// #define KEY_9_GT314_MAP 11
// #define KEY_STAR_GT314_MAP 1
// #define KEY_ENTER_GT314_MAP 12
// #define KEY_LOCKED_GT314_MAP 13
// #define KEY_DOORBELL_GT314_MAP 0
static int32_t GT31X_Read(VirtualHardware_enum_t dev, void *data, uint32_t len, uint32_t param)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!GT31X_reg_init)
        {
            GT31X_LOG("GT31X_reg_init: %d",  GT31X_reg_init);
            return 1;
        }
        // uint8_t keystring[16] = {'B', '*', '7', '4', '1', '0', '8', '5', '2', '3', '6', '9', '#', 'L', 'A', 'A'};
        uint8_t keystring[16] = {'8', '0', '*', '5', '7', '4', '2', '1', '3', '6', '#', '9', 'A', 'A', 'A', 'A'};
        uint8_t i, abKey[2];
        TouchRead(mTouchAddrKeyRead, abKey, 2);
        uint16_t keyValue = ((abKey[1] << 8) | abKey[0]);
        for (i = 0; i < 16; i++)
        {
            if (keyValue & (1 << i))
            {
                *(uint8_t *)data = keystring[i];
                //GT31X_LOG("data:%c ---index:%d",  keystring[i], i);
                break;
            }
        }
    }
    return 0;
}
static int32_t GT31X_Write(VirtualHardware_enum_t dev, void *data, uint32_t len, uint32_t param)
{
    if (vCAP_SENSE2 == dev)
    {
        if (param == 0)
        {
            Device_Write(vPIN_C38, NULL, 0, 0);
            return 1;
        }
        else if (param == 1)
        {
            Device_Write(vPIN_C38, NULL, 0, 1);
            co_delay_ms(10);
            GT31X_Register_Init();
        }
    }
    return 0;
}
static int8_t GT31X_Disable(VirtualHardware_enum_t dev)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!GT31X_reg_init)
        {
            return -1;
        }
        GT31X_LOG("GT31X_Disable \r\n");
        TouchWriteByte(0x14, 0x02); /* 按键扫描时间约 200ms 左右，时间越长功耗越低*/
        TouchWriteByte(0x19, 0x00); /* 关闭滑动模式 */
    }
    
    Device_Disable(GT31X_VIRTUALHARDWARE);
    return 0;
}

static int8_t GT31X_Enable(VirtualHardware_enum_t dev)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!GT31X_reg_init)
        {
            return -1;
        }
        GT31X_LOG("GT31X_Enable \r\n");
        TouchWriteByte(0x14, 0x00); /*按键扫描时间 11ms 左右*/
        TouchWriteByte(0x19, 0x01); /*开启滑动模式*/
    }
    return 0;
}
/**
 * @brief GT31X设备初始化
 *
 *
 * @note
 */
static void GT31X_Init(void)
{
    GT31X_LOG("GT31X init");
    /* gpio初始化 */
    GT31X_Rest();
    // GT31X_init();
    GT31X_Register_Init();
    Device_stu_t *dcb = Device_GetDeviceCtrlBlock(vCAP_SENSE);
    dcb->read = GT31X_Read;
    dcb->write = GT31X_Write;
    dcb->disable = GT31X_Disable;
    dcb->enable = GT31X_Enable;
}
INIT_DEVICE_EXPORT(GT31X_Init);
